

package Game;

import java.awt.Point;

/**
 *
 * Compiler: jdk1.6.0_14 <br />
 * IDE: NetBeans 6.7.1 <br />
 * @author Andrew Smith <br />
 */
public enum Direction
{
    //the enums;
    North, NorthNorthEast, NorthEast, NorthEastEast, East, SouthEastEast, SouthEast,
    SouthSouthEast, South, SouthSouthWest, SouthWest, SouthWestWest, West, NorthWestWest, NorthWest, NorthNorthWest;


    //the following static variables are the rotation values
    private static final double DEGREE_INC = (Math.PI / 4)/2;

    private static final double DEGREE_0 = 0;
    private static final double DEGREE_23 = DEGREE_0 + DEGREE_INC;  //NEW VALUE
    private static final double DEGREE_45 = DEGREE_23 + DEGREE_INC;
    private static final double DEGREE_68 = DEGREE_45 + DEGREE_INC;  //NEW VALUE
    private static final double DEGREE_90 = DEGREE_68 + DEGREE_INC;
    private static final double DEGREE_113 = DEGREE_90 + DEGREE_INC;  //NEW VALUE
    private static final double DEGREE_135 = DEGREE_113 + DEGREE_INC;
    private static final double DEGREE_158 = DEGREE_135 + DEGREE_INC;  //NEW VALUE
    private static final double DEGREE_180 = DEGREE_158 + DEGREE_INC;
    private static final double DEGREE_203 = 0 - (DEGREE_INC*7);  //NEW VALUE
    private static final double DEGREE_225 = 0 - (DEGREE_INC*6);
    private static final double DEGREE_248 = 0 - (DEGREE_INC*5);  //NEW VALUE
    private static final double DEGREE_270 = 0 - (DEGREE_INC*4);
    private static final double DEGREE_293 = 0 - (DEGREE_INC*3);  //NEW VALUE
    private static final double DEGREE_315 = 0 - (DEGREE_INC*2);
    private static final double DEGREE_338 = 0 - (DEGREE_INC*1);  //NEW VALUE

    /** a list of all the direction values in order */
    public static final double[] ROTATIONS = {DEGREE_0, DEGREE_23, DEGREE_45, DEGREE_68, DEGREE_90, DEGREE_113, DEGREE_135, DEGREE_158, DEGREE_180,
                                                DEGREE_203, DEGREE_225, DEGREE_248, DEGREE_270, DEGREE_293, DEGREE_315, DEGREE_338};
    /** a list of all the directions in order */
    public static final Direction[] DIRECTIONS = {North, NorthNorthEast, NorthEast, NorthEastEast, East, SouthEastEast, SouthEast, SouthSouthEast, South,
                                                    SouthSouthWest, SouthWest, SouthWestWest, West, NorthWestWest, NorthWest, NorthNorthWest};

    /**
     * Gets the value of this Direction
     * @return the value of the direction
     */
    public double getValue()
    {
        switch(this)
        {
            case North: return DEGREE_0;
            case NorthNorthEast: return DEGREE_23; //NEW VALUE
            case NorthEast: return DEGREE_45;
            case NorthEastEast: return DEGREE_68; //NEW VALUE
            case East: return DEGREE_90;
            case SouthEastEast: return DEGREE_113; //NEW VALUE
            case SouthEast: return DEGREE_135;
            case SouthSouthEast: return DEGREE_158; //NEW VALUE
            case South: return DEGREE_180;
            case SouthSouthWest: return DEGREE_203; //NEW VALUE
            case SouthWest: return DEGREE_225;
            case SouthWestWest: return DEGREE_248; //NEW VALUE
            case West: return DEGREE_270;
            case NorthWestWest: return DEGREE_293; //NEW VALUE
            case NorthWest: return DEGREE_315;
            case NorthNorthWest: return DEGREE_338; //NEW VALUE
            default: return 0;
        }
    }

    //arrays of movement coordinates
    private static final int ST = 3; //the straight movement value (ie when the tank is looking up, down, left, right)
    private static final int DI = 2; //the diagonal movement value (ie when the tank is looking diagonally)
    private static final int DZ = DI/2; //the diagonal movement value (ie when the tank is looking half diagonally and half straight)
    //                                         N  NNW   NW   NWW  W  SWW SW  SSW  S  SSE   SE  SEE    E  NEE   NE  NNE
    private static final int[] xPositions = {  0,  DZ,  DI,  DI, ST, DI, DI, DZ,  0, -DZ, -DI, -DI, -ST, -DI, -DI, -DZ};
    private static final int[] yPositions = {-ST, -DI, -DI, -DZ,  0, DZ, DI, DI, ST,  DI,  DI,  DZ,   0, -DZ, -DI, -DI};


    /**
     * Gets the next point value that this direction has
     * @return
     */
    public Point getNextPointValue()
    {
        switch(this)
        {
            case North: return new Point(xPositions[0], yPositions[0]);
            case NorthNorthEast: return new Point(xPositions[1], yPositions[1]); //NEW VALUE
            case NorthEast: return new Point(xPositions[2], yPositions[2]);
            case NorthEastEast: return new Point(xPositions[3], yPositions[3]); //NEW VALUE
            case East: return new Point(xPositions[4], yPositions[4]);
            case SouthEastEast: return new Point(xPositions[5], yPositions[5]); //NEW VALUE
            case SouthEast: return new Point(xPositions[6], yPositions[6]);
            case SouthSouthEast: return new Point(xPositions[7], yPositions[7]); //NEW VALUE
            case South: return new Point(xPositions[8], yPositions[8]);
            case SouthSouthWest: return new Point(xPositions[9], yPositions[9]); //NEW VALUE
            case SouthWest: return new Point(xPositions[10], yPositions[10]);
            case SouthWestWest: return new Point(xPositions[11], yPositions[11]); //NEW VALUE
            case West: return new Point(xPositions[12], yPositions[12]);
            case NorthWestWest: return new Point(xPositions[13], yPositions[13]); //NEW VALUE
            case NorthWest: return new Point(xPositions[14], yPositions[14]);
            case NorthNorthWest: return new Point(xPositions[15], yPositions[15]); //NEW VALUE
            default: return new Point(0, 0);
        }
    }


    /**
     * Gets a new direction, based on what this direction is
     */
    public Direction getDirection()
    {
        switch(this)
        {

            case North: return Direction.North;
            case NorthNorthEast: return Direction.NorthNorthEast;
            case NorthEast: return Direction.NorthEast;
            case NorthEastEast: return Direction.NorthEastEast;
            case East: return Direction.East;
            case SouthEastEast: return Direction.SouthEastEast;
            case SouthEast: return Direction.SouthEast;
            case SouthSouthEast: return Direction.SouthSouthEast;
            case South: return Direction.South;
            case SouthSouthWest: return Direction.SouthSouthWest;
            case SouthWest: return Direction.SouthWest;
            case SouthWestWest: return Direction.SouthWestWest;
            case West: return Direction.West;
            case NorthWestWest: return Direction.NorthWestWest;
            case NorthWest: return Direction.NorthWest;
            case NorthNorthWest: return Direction.NorthNorthWest;
            default: return Direction.North;
        }
    }


    @Override
    public String toString()
    {
        switch(this)
        {
            case North: return "North";
            case NorthEast: return "NorthEast";
            case East: return "East";
            case SouthEast: return "SouthEast";
            case South: return "South";
            case SouthWest: return "SouthWest";
            case West: return "West";
            case NorthWest: return "NorthWest";
            default: return "null";
        }
    }

}
